# 创建时间:2023/3/29 22:58
# 创建人:天霄
# 计划 :SenjoTwintail
# 文件 :SurfaceGenerater.py
# 基于 Python 3.8.2
# ========================================
# 图像快捷生成封装
# ========================================
import pygame
from BasePygame.Gamer import LoadImage
from BasePygame.Public import flagBox


def generate_list_normal_1in1(frame: pygame.Surface,
                              contents_surfaces: list,
                              space: int,
                              keep_left=0,
                              first_keep_top=0,
                              function_locate_each=None):
    """生成简单的透明背景list图像，每行一个内容

    :param frame: 背景对象
    :param contents_surfaces: 列表内容图
    :param space: 列表每个图之间的间距，即空隙
    :param keep_left: 列表距离背景左侧的距离（x轴），默认0
    :param first_keep_top: 第一张列表图距离背景图顶部的距离（y轴），默认0
    :param function_locate_each: 对每个内容图所做的函数，第一个参数为该图片对象，第二个为y
    :return:
    """
    bg_size = frame.get_size()
    y2 = first_keep_top
    for c in contents_surfaces:
        cs = c
        if isinstance(c, LoadImage):
            c.setTopleft((0, -10000))
            cs = c.surface
        if y2 + space + cs.get_size()[1] < 0:
            y2 += space + cs.get_size()[1]
            continue
        frame.blit(cs, (keep_left, y2))
        if function_locate_each is not None:
            function_locate_each(c, y2)
        y2 += space + cs.get_size()[1]
        if y2 > bg_size[1]: break

    return frame


def generate_list_with_mask_same1in1(bg_surface: pygame.Surface,
                                     contents_surfaces: list,
                                     space: int,
                                     bg_alpha=255,
                                     keep_left=0,
                                     first_keep_top=0,
                                     function_locate_each=None):
    """生成带背景遮罩的list图像，每行一个相同高度的内容

    :param bg_surface: 背景图
    :param contents_surfaces: 列表内容图
    :param space: 列表每个图原点的间距，即位移
    :param bg_alpha: 背景透明度，默认不透明255
    :param keep_left: 列表距离背景左侧的距离（x轴），默认0
    :param first_keep_top: 第一张列表图距离背景图顶部的距离（y轴），默认0
    :param function_locate_each: 对每个内容图所做的函数，第一个参数为该图片对象，第二个为y
    :return:
    """
    bg = bg_surface.copy()
    '''初始图，衬底透明度'''
    bg_sub = bg.copy()
    '''这是”不需要“的剪影部分。用于限定切割此区域，留下需要的部分'''
    bg_content = bg.copy()
    '''用于呈现内容的主图像'''
    bgsize = bg.get_size()
    frame = pygame.Surface(bgsize, pygame.SRCALPHA).convert_alpha()
    '''用于把所有内容物放在一个区域'''

    y = y2 = first_keep_top
    for cc in contents_surfaces:
        ccs = cc
        if isinstance(cc, LoadImage):
            ccs = cc.surface
        if y + ccs.get_size()[1] < 0:
            y += space + ccs.get_size()[1]
            continue
        bg_sub.blit(ccs, (keep_left, y), None, pygame.BLEND_RGBA_SUB)
        y += space + ccs.get_size()[1]
        if y > bgsize[1]: break
    bg_content.blit(bg_sub, (0, 0), None, pygame.BLEND_RGBA_SUB)
    for c in contents_surfaces:
        cs = c
        if isinstance(c, LoadImage):
            c.setTopleft((0, -10000))
            cs = c.surface
        if y2 + cs.get_size()[1] < 0:
            y2 += space + cs.get_size()[1]
            continue
        bg_content.blit(cs, (keep_left, y2), None, pygame.BLEND_RGB_ADD)
        if function_locate_each is not None:
            function_locate_each(c, y2)
        y2 += space + cs.get_size()[1]
        if y2 > bgsize[1]: break

    bg.set_alpha(bg_alpha)
    frame.blit(bg, (0, 0))
    frame.blit(bg_content, (0, 0))
    return frame


def update_location_w(w_before: int, clickable_flag: bool, speed: int, min_w: int, max_w=0, dragging_function=None):
    """拖拽或滚动滚轮后更新纵坐标值

    :param w_before: 之前的纵坐标值
    :param clickable_flag: 拖拽或滑动的第二判断条件，布尔值（例如：是否在点击范围内）
    :param speed: 滚动滚轮的速度
    :param min_w: w最小值
    :param max_w: w最大值，默认为0
    :param dragging_function: 如果判定有拖拽或滑动后需执行的函数
    :return: w_before
    """
    temp_w = w_before
    if flagBox.pressed[0] and clickable_flag:
        temp_w += flagBox.rel[1]
        if dragging_function is not None: dragging_function()
    if flagBox.clickOnce[3] and clickable_flag:
        temp_w += flagBox.clickOnce[3] * speed
        if dragging_function is not None: dragging_function()
    elif flagBox.clickOnce[4] and clickable_flag:
        temp_w -= (flagBox.clickOnce[4] - 1) * speed
        if dragging_function is not None: dragging_function()
    if temp_w <= min_w:
        w_before = min_w
    elif temp_w >= max_w:
        w_before = max_w
    else:
        w_before = temp_w
    return w_before

